package handlers

import (
	"restaurant-system/config"
	"restaurant-system/internal/models"
	"strconv"
	"time"
	"errors"
	"fmt"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// 更新用户偏好请求
type UpdatePreferenceRequest struct {
	FavCategories  []string `json:"fav_categories"`
	FavTags        []string `json:"fav_tags"`
	SpicyLevel     int      `json:"spicy_level"`
	DietaryNeeds   []string `json:"dietary_needs"`
	Allergies      []string `json:"allergies"`
	DislikedDishes []uint   `json:"disliked_dishes"`
}

// 更新用户偏好
func UpdatePreference(c *gin.Context) {
	userID, _ := c.Get("userID")
	fmt.Printf("Updating preferences for userID: %v\n", userID)

	var preference models.UserPreference
	
	// 先获取现有的偏好设置
	if err := config.DB.Where("user_id = ?", userID).First(&preference).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			// 如果不存在，创建新的偏好设置
			preference = models.UserPreference{
				UserID: userID.(uint),
				FavCategories:  models.StringList{},
				FavTags:       models.StringList{},
				SpicyLevel:    0,
				DietaryNeeds:  models.StringList{},
				Allergies:     models.StringList{},
				DislikedDishes: models.UintList{},
			}
		} else {
			fmt.Printf("Error getting preference: %v\n", err)
			c.JSON(500, gin.H{"error": "获取偏好设置失败"})
			return
		}
	}

	// 绑定请求数据
	var req UpdatePreferenceRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		fmt.Printf("Error binding JSON: %v\n", err)
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	fmt.Printf("Received request data: %+v\n", req)

	// 确保所有数组字段都有值（即使是空数组）
	if req.FavCategories == nil {
		req.FavCategories = []string{}
	}
	if req.FavTags == nil {
		req.FavTags = []string{}
	}
	if req.DietaryNeeds == nil {
		req.DietaryNeeds = []string{}
	}
	if req.Allergies == nil {
		req.Allergies = []string{}
	}
	if req.DislikedDishes == nil {
		req.DislikedDishes = []uint{}
	}

	// 更新所有字段
	preference.FavCategories = models.StringList(req.FavCategories)
	preference.FavTags = models.StringList(req.FavTags)
	preference.SpicyLevel = req.SpicyLevel
	preference.DietaryNeeds = models.StringList(req.DietaryNeeds)
	preference.Allergies = models.StringList(req.Allergies)
	preference.DislikedDishes = models.UintList(req.DislikedDishes)

	var err error
	if preference.ID == 0 {
		err = config.DB.Create(&preference).Error
	} else {
		err = config.DB.Save(&preference).Error
	}

	if err != nil {
		fmt.Printf("Error saving preference: %v\n", err)
		c.JSON(500, gin.H{"error": "保存偏好设置失败"})
		return
	}

	c.JSON(200, gin.H{
		"message": "更新成功",
		"preference": preference,
	})
}

// 收藏/取消收藏菜品
func ToggleFavorite(c *gin.Context) {
	userID, _ := c.Get("userID")
	dishID := c.Param("id")
	note := c.Query("note")

	// 转换 dishID 为 uint
	dishIDUint, err := strconv.ParseUint(dishID, 10, 32)
	if err != nil {
		c.JSON(400, gin.H{"error": "无效的菜品ID"})
		return
	}

	var favorite models.UserFavorite
	result := config.DB.Where("user_id = ? AND dish_id = ?", userID, uint(dishIDUint)).First(&favorite)

	if result.Error == nil {
		// 已存在，删除收藏
		if err := config.DB.Delete(&favorite).Error; err != nil {
			c.JSON(500, gin.H{"error": "取消收藏失败"})
			return
		}
		c.JSON(200, gin.H{"message": "取消收藏成功"})
		return
	}

	// 不存在，添加收藏
	favorite = models.UserFavorite{
		UserID: userID.(uint),
		DishID: uint(dishIDUint),
		Note:   note,
	}

	if err := config.DB.Create(&favorite).Error; err != nil {
		c.JSON(500, gin.H{"error": "添加收藏失败"})
		return
	}

	c.JSON(200, gin.H{"message": "添加收藏成功", "favorite": favorite})
}

// 记录浏览历史
func RecordBrowsingHistory(c *gin.Context) {
	userID, _ := c.Get("userID")
	dishID := c.Param("id")

	// 转换 dishID 为 uint
	dishIDUint, err := strconv.ParseUint(dishID, 10, 32)
	if err != nil {
		c.JSON(400, gin.H{"error": "无效的菜品ID"})
		return
	}

	var history models.BrowsingHistory
	result := config.DB.Where("user_id = ? AND dish_id = ?", userID, uint(dishIDUint)).First(&history)

	if result.Error == nil {
		// 已存在，更新浏览次数和时间
		if err := config.DB.Model(&history).Updates(map[string]interface{}{
			"view_count":  history.ViewCount + 1,
			"last_viewed": time.Now(),
		}).Error; err != nil {
			c.JSON(500, gin.H{"error": "更新浏览记录失败"})
			return
		}
	} else {
		// 不存在，创建新记录
		history = models.BrowsingHistory{
			UserID:     userID.(uint),
			DishID:     uint(dishIDUint),
			ViewCount:  1,
			LastViewed: time.Now(),
		}
		if err := config.DB.Create(&history).Error; err != nil {
			c.JSON(500, gin.H{"error": "创建浏览记录失败"})
			return
		}
	}

	c.JSON(200, gin.H{"message": "记录浏览历史成功"})
}

// 获取用户订单统计
func GetOrderStats(c *gin.Context) {
	userID, _ := c.Get("userID")

	var stats models.OrderStats
	if err := config.DB.Where("user_id = ?", userID).First(&stats).Error; err != nil {
		// 如果没有统计记录，创建一个空的
		stats = models.OrderStats{
			UserID:        userID.(uint),
			FavDishes:     models.UintList{},
			FavCategories: models.StringList{},
			FavStores:     models.UintList{},
		}
		if err := config.DB.Create(&stats).Error; err != nil {
			c.JSON(500, gin.H{"error": "创建订单统计失败"})
			return
		}
	}

	c.JSON(200, gin.H{"stats": stats})
}

// 更新订单统计（在订单完成时调用）
func UpdateOrderStats(userID uint, order models.Order) error {
	tx := config.DB.Begin()

	var stats models.OrderStats
	result := tx.Where("user_id = ?", userID).First(&stats)

	if result.Error != nil {
		// 不存在，创建新统计
		stats = models.OrderStats{
			UserID:      userID,
			TotalOrders: 1,
			TotalAmount: order.TotalAmount,
		}
		if err := tx.Create(&stats).Error; err != nil {
			tx.Rollback()
			return err
		}
	} else {
		// 更新现有统计
		updates := map[string]interface{}{
			"total_orders":     stats.TotalOrders + 1,
			"total_amount":     stats.TotalAmount + order.TotalAmount,
			"avg_order_amount": (stats.TotalAmount + order.TotalAmount) / float64(stats.TotalOrders+1),
			"last_order_time":  time.Now(),
		}

		if err := tx.Model(&stats).Updates(updates).Error; err != nil {
			tx.Rollback()
			return err
		}
	}

	tx.Commit()
	return nil
}

// 获取用户偏好
func GetPreference(c *gin.Context) {
	userID, _ := c.Get("userID")
	fmt.Printf("Getting preferences for userID: %v\n", userID)

	var preference models.UserPreference
	err := config.DB.Where("user_id = ?", userID).First(&preference).Error
	if err != nil {
		fmt.Printf("Error getting preference: %v\n", err)
		if errors.Is(err, gorm.ErrRecordNotFound) {
			fmt.Println("Creating new preference")
			// 如果不存在，创建一个新的空偏好设置
			preference = models.UserPreference{
				UserID:         userID.(uint),
				FavCategories:  []string{},
				FavTags:       []string{},
				SpicyLevel:    0,
				DietaryNeeds:  []string{},
				Allergies:     []string{},
				DislikedDishes: []uint{},
			}
			if err := config.DB.Create(&preference).Error; err != nil {
				fmt.Printf("Error creating preference: %v\n", err)
				c.JSON(500, gin.H{"error": "创建偏好设置失败"})
				return
			}
			fmt.Println("New preference created successfully")
		} else {
			c.JSON(500, gin.H{"error": "获取偏好设置失败"})
			return
		}
	}

	fmt.Printf("Returning preference: %+v\n", preference)
	c.JSON(200, gin.H{"preference": preference})
}

// 获取收藏列表
func GetFavorites(c *gin.Context) {
	userID, _ := c.Get("userID")
	
	// 获取分页参数
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))
	
	var total int64
	var favorites []models.UserFavorite
	
	// 获取总数
	if err := config.DB.Model(&models.UserFavorite{}).Where("user_id = ?", userID).Count(&total).Error; err != nil {
		c.JSON(500, gin.H{"error": "获取收藏总数失败"})
		return
	}
	
	// 获取分页数据
	if err := config.DB.Where("user_id = ?", userID).
		Preload("Dish").
		Order("created_at desc").
		Offset((page - 1) * pageSize).
		Limit(pageSize).
		Find(&favorites).Error; err != nil {
		c.JSON(500, gin.H{"error": "获取收藏列表失败"})
		return
	}
	
	c.JSON(200, gin.H{
		"favorites": favorites,
		"total": total,
		"page": page,
		"pageSize": pageSize,
	})
}

// 获取浏览历史
func GetBrowsingHistory(c *gin.Context) {
	userID, _ := c.Get("userID")

	var history []models.BrowsingHistory
	if err := config.DB.Where("user_id = ?", userID).
		Preload("Dish").
		Order("last_viewed desc").
		Find(&history).Error; err != nil {
		c.JSON(500, gin.H{"error": "获取浏览历史失败"})
		return
	}

	c.JSON(200, gin.H{"history": history})
}
